<template>
  <vxe-modal
    resize
    esc-closable
    width="90%"
    height="97%"
    showFooter
    v-model="formVisible"
    :loading="formLoading"
    @hide="()=>{ $emit(`close`) }"
  >
    <template slot="title">
      <span>单表快速开发</span>
    </template>
    <template>
      <el-scrollbar class="scrollbar-handle">
        <!-- 步骤条 -->
        <el-steps :active="active" finish-status="success" simple>
          <el-step title="数据表选择"></el-step>
          <el-step title="字段配置"></el-step>
          <el-step title="字段选择"></el-step>
          <el-step title="信息配置"></el-step>
          <el-step title="查看代码"></el-step>
        </el-steps>
        <!-- 数据表选择 -->
        <div v-show="active === 0" class="step_div">
          <vxe-grid
            ref="firstTable"
            align="left"
            :toolbar="firstTableToolbar"
            :columns="firstTableColumn"
            :data="firstTableData"
            :expand-config="{ lazy: true, loadMethod: expanded }"
            row-id="name"
            :radio-config="{ trigger: 'row'}"
            :sync-resize="formVisible"
          >
            <!-- 业务按钮 -->
            <template v-slot:toolbar_buttons></template>
            <!-- 快速查询 -->
            <template v-slot:toolbar_search>
              <rayd-quick-query v-model="filterName" @query="loadTables"></rayd-quick-query>
            </template>
            <!--  子表格模板 -->
            <template v-slot:subTable="{ row }">
              <vxe-grid
                :ref="`subTable` + row._XID"
                height="250"
                :columns="firstTableSubColumn"
                :data="row.detail"
              >
                <!-- 允许空模板 -->
                <template v-slot:f_isnullable="{ row }">
                  <el-tag
                    effect="dark"
                    :type="row.f_isnullable === '1' ? 'success' : 'info'"
                    >{{ row.f_isnullable === "1" ? "是" : "否" }}</el-tag
                  >
                </template>
                <!-- 主键模板 -->
                <template v-slot:f_key="{ row }">
                  <el-tag
                    effect="dark"
                    :type="row.f_key === '1' ? 'success' : 'info'"
                    >{{ row.f_key === "1" ? "是" : "否" }}</el-tag
                  >
                </template>
              </vxe-grid>
            </template>
          </vxe-grid>
        </div>
        <!-- 字段配置 -->
        <div v-show="active === 1" class="step_div">
            <vxe-grid
                ref="secondTable"
                align="left"
                toolbar
                :columns="secondTableColumn"
                :data="config.FieldList"
                :edit-config="{ mode: 'row' }"
                :edit-rules="rules"
                :highlight-current-row="false"
                :mouse-config="{selected: true}"
                :keyboard-config="{isArrow: true, isDel: true, isEnter:true, isTab: true, isEdit: true}"
                :sync-resize="active">
                <!-- 业务按钮 -->
                <template v-slot:toolbar_buttons></template>
                <!-- 快速查询 -->
                <template v-slot:toolbar_search>
                  <el-radio-group v-model="config.IsTree">
                    <el-radio :label="false">非树型结构</el-radio>
                    <el-radio :label="true">树型结构</el-radio>
                  </el-radio-group>
                </template>
            </vxe-grid>
        </div>
        <!-- 字段选择 -->
        <div v-show="active === 2" class="step_div">
         <el-row :gutter="10">
          <el-col :span="24" :sm="24" :lg="8">
            <el-card>
                <div slot="header"><el-tag type="info" size='medium'><h2>表单配置</h2></el-tag></div>
                <el-tree
                    ref="firstTree"
                    default-expand-all
                    check-on-click-node
                    :expand-on-click-node="false"
                    :data="fieldList"
                    node-key="Name"
                    :props="{ children:'children', label: 'Remark'}"
                    show-checkbox
                    :render-content="renderContent"
                ></el-tree>
            </el-card>
          </el-col>
          <el-col :span="24" :sm="24" :lg="8">
            <el-card>
                <div slot="header">
                  <div style="flex: 1; display: flex;align-items: center;justify-content: space-between;font-size: 14px;padding-right: 8px;">
                    <el-tag type="info" size='medium'><h2>列表配置</h2></el-tag>
                    <el-radio-group v-model="config.IsPage">
                      <el-radio :label="false">不分页</el-radio>
                      <el-radio :label="true">分页</el-radio>
                    </el-radio-group>
                  </div>
                </div>
                <el-tree
                    ref="secondTree"
                    default-expand-all
                    check-on-click-node
                    :expand-on-click-node="false"
                    :data="fieldList"
                    node-key="Name"
                    :props="{ children:'children', label: 'Remark'}"
                    show-checkbox
                    :render-content="renderContent"
                ></el-tree>
            </el-card>
          </el-col>
          <el-col :span="24" :sm="24" :lg="8">
            <el-card>
                <div slot="header"><el-tag type="info" size='medium'><h2>查询条件配置</h2></el-tag></div>
                <el-tree
                    ref="thirdTree"
                    default-expand-all
                    check-on-click-node
                    :expand-on-click-node="false"
                    :data="fieldList"
                    node-key="Name"
                    :props="{ children:'children', label: 'Remark'}"
                    show-checkbox
                    :render-content="renderContent"
                ></el-tree>
            </el-card>
          </el-col>
         </el-row>
        </div>
        <!-- 信息配置 -->
        <div v-show="active === 3" class="step_div">
            <el-alert 
                title="信息配置" 
                description="配置物理文件生成路径，目录层级对应模块与应用域" 
                :closable="false" type="info" show-icon effect="dark">
            </el-alert>
            <vxe-form
                ref="firstForm"
                title-width="120"
                title-align="right"
                :data="config"
                :rules="rules"
                span="8"
            >
                <vxe-form-item title="区域" field="Area">
                  <rayd-select options="AreaSelect" v-model="config.Area"></rayd-select>
                </vxe-form-item>
                <vxe-form-item title="模块" field="Module">
                  <rayd-select options="ModuleSelect" v-model="config.Module"></rayd-select>
                </vxe-form-item>
                <vxe-form-item title="应用域" field="AppDomain">
                  <el-input v-model="config.AppDomain" placeholder="请输入" clearable></el-input>
                </vxe-form-item>
                <vxe-form-item title="前端项目路径" field="FontSrcPath" span="16">
                  <el-input v-model="config.FontSrcPath" placeholder="例如：D:\rfid_gdzc\Source\front-end\src" clearable @blur="updatePath"></el-input>
                </vxe-form-item>
            </vxe-form>
            <el-alert 
                title="系统功能配置" 
                description="配置系统功能菜单、功能按钮" 
                :closable="false" type="info" show-icon effect="dark">
            </el-alert>
            <vxe-form
                ref="secondForm"
                title-width="120"
                title-align="right"
                :data="config.ModuleEntity"
                :rules="rules"
                span="9"
            >
                <vxe-form-item
                  title="模块编码"
                  field="B_EnCode"
                  :title-suffix="{ message: '模块编码不能重复！', icon: 'fa fa-exclamation-circle' }"
                >
                  <el-input v-model="config.ModuleEntity.B_EnCode" placeholder="请输入" clearable></el-input>
                </vxe-form-item>
                <vxe-form-item
                  title="模块名称"
                  field="B_FullName"
                  :title-suffix="{ message: '模块名称不能重复！', icon: 'fa fa-exclamation-circle' }"
                >
                  <el-input v-model="config.ModuleEntity.B_FullName" placeholder="请输入" clearable></el-input>
                </vxe-form-item>
                <vxe-form-item title="所属模块">
                  <rayd-select :options="moduleTreeIds" v-model="config.ModuleEntity.B_ParentId" tree-config></rayd-select>
                </vxe-form-item>
                <vxe-form-item title="排序码" span="8">
                  <el-input-number
                    :controls="false"
                    :min="0"
                    v-model="config.ModuleEntity.B_SortCode"
                  ></el-input-number>
                </vxe-form-item>
                <vxe-form-item title="模块图标" span="24">
                  <e-icon-picker v-model="config.ModuleEntity.B_Icon" />
                </vxe-form-item>
                <vxe-form-item title="描述" span="24">
                  <el-input
                    type="textarea"
                    :autosize="{ minRows: 4, maxRows: 4}"
                    placeholder="请输入"
                    clearable
                    v-model="config.ModuleEntity.B_Description"
                  ></el-input>
                </vxe-form-item>
            </vxe-form>
        </div>
        <!-- 查看代码 -->
        <div v-show="active === 4" class="step_div">
            <el-tabs v-model="tabName" type="border-card">
              <el-tab-pane label="实体层代码" name="first">
                <coder v-if="tabName === 'first'" v-model="previewCode.entityCode" language="Java"/>
              </el-tab-pane>
              <el-tab-pane label="应用层代码" name="second">
                <coder v-if="tabName === 'second'" v-model="previewCode.appCode" language="Java"/>
              </el-tab-pane>
              <el-tab-pane label="表现层代码" name="third">
                <coder v-if="tabName === 'third'" v-model="previewCode.controllerCode" language="Java"/>
              </el-tab-pane>
              <el-tab-pane label="页面代码" name="fourth">
                <coder v-if="tabName === 'fourth'" v-model="previewCode.indexCode" language="Java"/>
              </el-tab-pane>
              <el-tab-pane label="表单代码" name="fifth">
                <coder v-if="tabName === 'fifth'" v-model="previewCode.formCode" language="Java"/>
              </el-tab-pane>
            </el-tabs>
        </div>
      </el-scrollbar>
    </template>
    <template slot="footer">
      <el-button type="primary" @click="previous" :disabled="active === 0">上一步</el-button>
      <el-button type="primary" @click="next">{{this.active === 4 ? `完成`:`下一步`}}</el-button>
      <el-button type="warning" v-form-validate="generate" v-if="this.active === 3">直接生成</el-button>
    </template>
  </vxe-modal>
</template>

<script>
import { DatabaseTable, CodeGenerator, Module } from "@/api";
import coder from "@/components/Codemirror";
export default {
  props: {},
  components: { coder },
  computed: {
    //字段选择
    fieldList() {
      return [
        {
          Name: '',
          Remark : `全选`,
          children : this.config.FieldList  
        }
      ];
    },
  },
  data() {
    return {
      //表单可见
      formVisible: true,
      //表单加载中
      formLoading: false,
      //存放表单ref数组
      formArr: ["firstForm","secondForm"],
      //表单实体
      config: {
          TableNames: [],
          FieldList: [],
          IsTree: false,
          IsPage: false,
          Area: '',
          Module: '',
          AppDomain: '',
          FontSrcPath: this.util.getStore({ name: 'fontsrcpath' }) || '',
          ModuleEntity: {}
      },
      //表单验证规则（规则键必须和表单键一致）
      rules: {
          Area: [{ required: true, message: "请选择区域!" }],
          Module: [{ required: true, message: "请选择模块!" }],
          AppDomain: [{ required: true, message: "请输入应用域!" }],
          FontSrcPath: [{ required: true, message: "请输入项目路径!" }],
          B_FullName: [
            {
              required: true,
              validator: ({ itemValue, property }) => {
                return new Promise((resolve, reject) => {
                  if (this.util.validateNull(itemValue)) {
                    reject(new Error("不能为空！"));
                  } else {
                    Module.ValidateExist({
                      id: this.config.ModuleEntity.B_ModuleId,
                      field: property,
                      value: itemValue,
                    })
                      .then((res) => {
                        resolve();
                      })
                      .catch((err) => {
                        reject(new Error("模块名称已存在！"));
                      });
                  }
                });
              },
            },
          ],
          B_EnCode: [
            {
              required: true,
              validator: ({ itemValue, property }) => {
                return new Promise((resolve, reject) => {
                  if (this.util.validateNull(itemValue)) {
                    reject(new Error("不能为空！"));
                  } else {
                    Module.ValidateExist({
                      id: this.config.ModuleEntity.B_ModuleId,
                      field: property,
                      value: itemValue,
                    })
                      .then((res) => {
                        resolve();
                      })
                      .catch((err) => {
                        reject(new Error("模块编码已存在！"));
                      });
                  }
                });
              },
            },
          ],
      },
      /* firstTable */
      filterName: "", //查询实体
      firstTableData: [], //表格实体
      //工具栏配置
      firstTableToolbar: {
        refresh: { 
          query : ()=> {
            this.filterName = ''; //清空条件
            this.loadTables();
          }
        },
        zoom: true,
        custom: true,
      },
      //列配置
      firstTableColumn: [
        {
          type: "radio",
          width: 50,
        },
        {
          type: "expand",
          width: 50,
          slots: { content: "subTable" },
        },
        {
          type: "seq",
          title: "序号",
          width: 80,
          align: "left",
        },
        { type: "html", field: "name", title: "表名", sortable: true },
        { type: "html", field: "sumrows", title: "记录条数", sortable: true },
        { type: "html", field: "data", title: "使用大小", sortable: true },
        {
          type: "html",
          field: "index_size",
          title: "索引使用大小",
          sortable: true,
        },
        { type: "html", field: "tdescription", title: "说明", sortable: true },
      ],
      //子列配置
      firstTableSubColumn: [
        {
          type: "seq",
          title: "序号",
          width: 80,
          align: "left",
        },
        { field: "f_column", title: "字段名", sortable: true, align: "left" },
        { field: "f_datatype", title: "数据类型", sortable: true },
        { field: "f_length", title: "长度", sortable: true },
        {
          field: "f_isnullable",
          title: "允许空",
          sortable: true,
          slots: { default: "f_isnullable" },
        },
        { field: "f_identity", title: "标识", sortable: true },
        {
          field: "f_key",
          title: "主键",
          sortable: true,
          slots: { default: "f_key" },
        },
        { field: "f_defaults", title: "默认值", sortable: true },
        {
          field: "f_remark",
          title: "说明",
          sortable: true,
          width: 200,
          align: "left",
        },
      ],
      /* secondTable */
      //列配置
      secondTableColumn:[
        { field: "Name", title: "字段" },
        { 
          field: "Remark", title: "名称" ,
          editRender: { name: "ElInput"},
          slots: {
            header: ({ column }) => {
              return [<span style="color: red;">{column.title}</span>];
            },
          },
        },
        { field: "FieldType", 
          title: "字段类型" , 
          editRender: {
            name: "ElSelect",
            options: this.util.getDataItemList("FieldType"),
            optionProps: { label: "label", value: "value" }
          },
          slots: {
            header: ({ column }) => {
              return [<span style="color: red;">{column.title}</span>];
            },
          },
        },
        {
          field: "FieldRule",
          title: "字段验证",
          editRender: {
            name: "ElSelect",
            options: this.util.getDataItemList("FieldRule"),
            optionProps: { label: "label", value: "value" }
          },
        },
        { field: "FieldStatistical", 
          title: "字段统计性" , 
          editRender: {
            name: "ElSelect",
            options: this.util.getDataItemList("FieldStatistical"),
            optionProps: { label: "label", value: "value" }
          },
        },
      ],

      /* 实体数据 */
      active: 0,
      tabName:'first',
      areaList: this.util.getDataItemList('AreaSelect'),
      moduleList: this.util.getDataItemList('ModuleSelect'),
      moduleTreeIds: [], //模块树型数据
      previewCode: { }
    };
  },
  created() {
    //初始化
    this.init();
  },
  methods: {
    //初始化
    init() {
      this.formLoading = true;
      Promise.all([
        Module.GetTreeList().then((res) => {
          this.moduleTreeIds = res;
        })
      ])
      .then(res=>{
        this.loadTables()
      })
    },
    //加载数据表
    loadTables() {
      this.formLoading = true;
      return DatabaseTable.GetList({queryjson:JSON.stringify({QueryInfo:this.filterName})}).then((res) => {
        this.firstTableData = res;
        this.formLoading = false;
      });
    },
    //行展开回调
    expanded({ row }) {
      return DatabaseTable.GetFieldList(row.name).then((res) => {
        row.detail = res;
      });
    },
    //树型节点内容自定义
    renderContent(h, { node, data, store }) {
        return (
          <span style="flex: 1; display: flex;align-items: center;justify-content: space-between;font-size: 14px;padding-right: 8px;">
            <span>{node.label}</span>
            <span>{data.Name}</span>
          </span>);
    },
    //上一步
    previous(){
        const currentStage = this.active;
        if (currentStage === 0){
            return;
        }else{
            this.active--;
        }
    },
    //下一步
    next(){
        const currentStage = this.active;
        if (currentStage === 0){
            // 保存表名
            let table = this.$refs['firstTable'].getRadioRecord();
            if(this.util.validateNull(table)){
              this.$message({ message: '请选择数据表', type: "warning"});
              return;
            }
            this.formLoading = true;
            this.config.TableNames = [table.name];
            // 获取字段集
            CodeGenerator.GetDefaultFieldList(table.name).then((res) => {
                //赋值 字段配置表格（从服务端获取基本字段配置）
                res.forEach(e => {
                  e.FieldRule = this.util.validateNull(e.FieldRule) ? null : e.FieldRule  + ``;
                  e.FieldType = this.util.validateNull(e.FieldType) ? null : e.FieldType  + ``;
                  e.FieldStatistical = this.util.validateNull(e.FieldStatistical) ? null : e.FieldStatistical  + ``;
                });
                this.config.FieldList = res;
                //勾选 字段选择（表单配置、列表配置默认全选）
                this.$refs["firstTree"].setCheckedKeys([''],true);
                this.$refs["secondTree"].setCheckedKeys([''],true);

                this.formLoading = false;
                this.active++;
            });
        }else if(currentStage === 1){
            this.active++;
        }else if(currentStage === 2){
            //获取 字段选择配置
            let formFields = this.$refs["firstTree"].getCheckedKeys(true);
            let gridFields = this.$refs["secondTree"].getCheckedKeys(true);
            let queryFields = this.$refs["thirdTree"].getCheckedKeys(true);
            //赋值 字段选择配置
            this.config.FieldList.forEach(field=>{
              if(formFields.find(c => field.Name ===c))
                field.ShowForm = true;
              if(gridFields.find(c => field.Name ===c))
                field.ShowGrid = true;
              if(queryFields.find(c => field.Name ===c))
                field.ShowQuery = true;
            })
            this.active++;
        }else if(currentStage === 3){
            this.util.formValidate(()=>{
                    // 验证通过
                    this.formLoading = true;
                    // 获取预览代码
                    CodeGenerator.PreviewRepidCode(this.config).then(res=>{
                      this.previewCode = res;
                      this.formLoading = false;
                      this.active++;
                    })
                })
        }else if(currentStage === 4){
          this.generate();
        }
    },
    //生成代码
    generate(){
          // 提交生成代码
          CodeGenerator.GenerateRepidCode(this.config).then(res=>{
            this.$emit("close");
          })
    },
    //缓存前端项目路径
    updatePath(){
      this.util.setStore({ name: 'fontsrcpath', content: this.config.FontSrcPath })
    }
  },
};
</script>

<style lang="less" scoped>
.step_div{
    margin-top:10px
}
</style>